package com.testtask.rightandabove.validate;

import com.testtask.rightandabove.entity.CD;
import com.testtask.rightandabove.entity.Catalog;
import com.testtask.rightandabove.tools.ServiceFunction;
import java.io.File;
import java.util.List;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import org.springframework.web.multipart.MultipartFile;

/**
 *
 * @author <a href="mailto:avereshchaga@gmail.com">Vereshchaga Alexey</a>
 */
public class XMLFileCorrectValidator implements ConstraintValidator<XMLFileCorrect, Object> {

    private String message = XMLFileCorrect.MESSAGE;

    @Override
    public void initialize(XMLFileCorrect constraintAnnotation) {
        this.message = constraintAnnotation.message();
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        Catalog catalog = null;
        MultipartFile file = (MultipartFile) value;
        if (file.isEmpty()) {
            String msg = "The field or file must not be empty";
            changeConstraintViolation(context, msg);
            return false;
        }

        if (!file.getOriginalFilename().matches(".+\\.{1}xml")) {
            String msg = "The file must have .xml extension";
            changeConstraintViolation(context, msg);
            return false;
        }

        if (file.getSize() > 1048576) {
            String msg = "The file must be less than 1MB";
            changeConstraintViolation(context, msg);
            return false;
        }
        try {
            File xmlFile = ServiceFunction.multipartToFile(file);
            JAXBContext jAXBContext = JAXBContext.newInstance(Catalog.class);
            Unmarshaller u = jAXBContext.createUnmarshaller();
            catalog = (Catalog) u.unmarshal(xmlFile);
        } catch (Exception e) {
            String msg = "Incompatible xml file content";
            changeConstraintViolation(context, msg);
            return false;
        }

        List<CD> cdList = catalog.getCds();
        for (CD cd : cdList) {
            if (cd.getArtist() == null
                    || cd.getCompany() == null
                    || cd.getCountry() == null
                    || cd.getPrice() == null
                    || cd.getTitle() == null
                    || cd.getYear() == null) {
                String msg = "Some properties of CD in catalog is null or incompatible type";
                changeConstraintViolation(context, msg);
                return false;
            }
        }
        return true;
    }

    private void changeConstraintViolation(ConstraintValidatorContext context,
            String message) {
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(message)
                .addConstraintViolation();
    }
}
